home *** CD-ROM | disk | FTP | other *** search
/ Mac-Source 1994 July / Mac-Source_July_1994.iso / C and C++ / System / lpDaemon SRC / lpd Sources / SpoolUtils.C < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-08  |  10.0 KB  |  431 lines  |  [TEXT/KAHL]

  1. /************************************************************************
  2.  *                                                                        *
  3.  * SpoolUtils.C                                                            *
  4.  *                                                                        *
  5.  *  Line Printer Daemon using TCP/IP printer protocol                    *
  6.  *                                                                        *
  7.  *    -------------- The spool file maintenance routines --------------    *
  8.  *                                                                        *
  9.  *  Written by Casper Boon, July, 1992.                                    *
  10.  *                                                                        *
  11.  *    © 1992, Casper Boon.                                                *
  12.  *                                                                        *
  13.  ************************************************************************/
  14.  
  15. #include "LPD.H"
  16. #include "Spooler.H"
  17. #include "TCPStream.H"
  18. #include "lpdProtos.H"
  19.  
  20.  
  21. integer spool_dir, spool_file;
  22. extern Boolean    printing;
  23.  
  24. char *cfA = "cfA";
  25.  
  26. Str255 SpoolFolder = "\pSpool Folder";
  27.  
  28.  
  29. /************************************************************************
  30.  ************************************************************************/
  31. void CreateSpoolFile(char *name, char*printer)
  32. {
  33.     char    *end, l;
  34.     OSErr    err;
  35.     integer    rRef, tVol;
  36.     Handle    tH;
  37.  
  38.     SetUpSpoolDir();
  39.     while (*name && *name != 'c' && *name != 'd') name++;
  40.     if DEBUGGING
  41.         log_printf("Creating spool file %s\n", name);
  42.  
  43.     end = name;
  44.     while (*end && *end != LF) end++;
  45.     *end = 0;
  46.     if (!(l = strlen(name)))
  47.         return;    /* no name */
  48.     *--name = l;
  49.  
  50.     Create((StringPtr)name, spool_dir, 'SIMN', 'TEXT');
  51.     if (err = FSOpen((StringPtr)name, spool_dir, &spool_file))
  52.         log_printf("Error creating spool file %s %d\n", name, err);
  53.  
  54.     if (name[1] == cfA[0])    /* control file */
  55.         {
  56.         end = printer;
  57.         while (*end && *end != LF) end++;
  58.         *end = 0;
  59.  
  60.         GetVol(NIL, &tVol);
  61.         SetVol(NIL, spool_dir);
  62.         CreateResFile((StringPtr)name);
  63.         rRef = OpenResFile((StringPtr)name);
  64.         SetVol(NIL, tVol);
  65.  
  66.         tH = NewHandle(strlen(printer) + 1);
  67.         HLock(tH);
  68.         BlockMove(printer, (*tH), strlen(printer)+1);
  69.         HUnlock(tH);
  70.         AddResource(tH, 'PRTR', 0, NIL);
  71.         CloseResFile(rRef);
  72.         DisposHandle(tH);
  73.         }
  74. }
  75.  
  76. /************************************************************************
  77.  ************************************************************************/
  78. void DeleteSpoolFile(StringPtr name)
  79. {
  80.     integer count = 0, cfRef, tRef;
  81.     Str63    buf;
  82.     Str255    prt_name_buf;
  83.  
  84.  
  85.     if (FSOpen(name, spool_dir, &cfRef))
  86.         {
  87.         log_printf(
  88.             "The control file %p disappeared before I could remove it?\n",
  89.                     name);
  90.         return;        /* error opening control file */
  91.         }
  92.  
  93.     while ( ReadLine(cfRef, (char*)buf, 61) )
  94.         {
  95.         if (buf[0] != 'U')    /* the file to unlink */
  96.             continue;
  97.         BlockMove(&buf[1], &prt_name_buf[1], strlen((char*)&buf[1]));
  98.         prt_name_buf[0] = strlen((char*)&buf[1]);
  99.         if DEBUGGING
  100.             log_printf("Dequeue %p\n", prt_name_buf);
  101.  
  102.         if (FSDelete(prt_name_buf, spool_dir))
  103.             {    /* the delete failed so try closing first */
  104.             if ( FSGetFRef(prt_name_buf, spool_dir, &tRef) == noErr )
  105.                 {
  106.                 FSClose(tRef);
  107.                 FSDelete(prt_name_buf, spool_dir);
  108.                 }
  109.             }
  110.         }
  111.  
  112.     FSClose(cfRef);
  113.     if DEBUGGING
  114.         log_printf("Dequeue %p\n", name);
  115.  
  116. #if 1
  117.     FSDelete(name, spool_dir);
  118. #else
  119.     log_printf("Renaming %p\n", name);
  120.     BlockMove(name, prt_name_buf, prt_name_buf[0]+1);
  121.     prt_name_buf[1] = '_';
  122.     Rename(name, spool_dir, prt_name_buf);    // rename the new one
  123. #endif
  124. }
  125.  
  126. /************************************************************************
  127.  ************************************************************************/
  128. void WriteSpoolFile(char*data, integer len)
  129. {
  130.     LongInt    count = len;
  131.     if (spool_file) FSWrite(spool_file, &count, data);
  132. }
  133.  
  134. /************************************************************************
  135.  ************************************************************************/
  136. void CloseSpoolFile()
  137. {
  138.     if (spool_file) FSClose(spool_file);
  139.     spool_file = 0;
  140. }
  141.  
  142. static Boolean last_was_cr = FALSE;
  143.  
  144. char ReadChar(integer fRef);
  145. /************************************************************************
  146.  ************************************************************************/
  147. char ReadChar(integer fRef)
  148. {
  149.     char c = fgetc(fRef);
  150.     if ( c == CR )
  151.         {
  152.         last_was_cr = TRUE;
  153.         return LF;
  154.         }
  155.     if ( c == LF && last_was_cr )
  156.         {    /* we ignore LF's after CR's */
  157.         c = fgetc(fRef);
  158.         if ( c == CR )
  159.             {
  160.             last_was_cr = TRUE;
  161.             return LF;
  162.             }
  163.         }
  164.     last_was_cr = FALSE;
  165.     return c;
  166. }
  167.  
  168.  
  169. /************************************************************************
  170.  ************************************************************************/
  171. integer ReadLine(integer fRef, char *buf, integer lim)
  172. {
  173.     integer i = 0;
  174.     char    c;
  175.     if (!buf)
  176.         {
  177.         while ((c=ReadChar(fRef)) && (c != LF)) ;    /* skip the line */
  178.         return c;
  179.         }
  180.     while ((c=ReadChar(fRef)) && (c != LF))
  181.         {
  182.         *buf++ = c;
  183.         if (i++ == lim)
  184.             {    /*that was number 31 */
  185.             while ((c=ReadChar(fRef)) && (c != LF)) ;    /* skip the rest */
  186.             break;    /* and get out of the loop */
  187.             }
  188.         }
  189.     *buf = 0;
  190.     return i;
  191. }
  192.  
  193. /************************************************************************
  194.  ************************************************************************/
  195. integer ReadCtlFile(StringPtr name, ctl_def * ctl)
  196. {
  197.     char    c;
  198.     integer    tVol, rRef, fRef;
  199.     Handle    tH;
  200.     LongInt    size;
  201.  
  202.     ctl->nFiles = 0;
  203.     ctl->printer[0] = 0;
  204.     ctl->class[0] = 0;
  205.     ctl->host[0] = 0;
  206.     ctl->src_name[0] = 0;
  207.     ctl->owner[0] = 0;
  208.  
  209.     GetVol(NIL, &tVol);
  210.     SetVol(NIL, spool_dir);
  211.     rRef = OpenResFile((StringPtr)name);
  212.     SetVol(NIL, tVol);
  213.  
  214.     if (rRef != -1)    /* which would indicate an error on the resource fork */
  215.         {
  216.         tH = GetResource('PRTR', 0);
  217.         size = GetHandleSize(tH);
  218.         HLock(tH);
  219.         BlockMove((*tH), ctl->printer, size);
  220.         HUnlock(tH);
  221.         CloseResFile(rRef);
  222.         }
  223.     else
  224.         {
  225.         ctl->printer[0] = 'l'; ctl->printer[1] = 'p'; ctl->printer[2] = 0;
  226.         }
  227.  
  228.     if (FSOpenRO(name, spool_dir, &fRef))
  229.         return -1;
  230.  
  231.     while (c = ReadChar(fRef))
  232.         {
  233.         switch (c)
  234.             {
  235.             case 'C' :    ReadLine(fRef, ctl->class, 30);
  236.                         break;
  237.             case 'H' :    ReadLine(fRef, ctl->host, 30);
  238.                         break;
  239.             case 'l' :
  240.             case 'f' :    if (ctl->src_name[0])
  241.                             strcat(ctl->src_name, ",...");
  242.                         else
  243.                             ReadLine(fRef, ctl->src_name, 30);
  244.                         ctl->nFiles++;
  245.                         break;
  246.             case 'P' :    ReadLine(fRef, ctl->owner, 30);
  247.                         break;
  248.             default:    ReadLine(fRef, NIL, 30);
  249.                         break;
  250.             }
  251.         }
  252.  
  253.     FSClose(fRef);
  254.     return 0;
  255. }
  256.  
  257.  
  258. /************************************************************************
  259.  ************************************************************************/
  260. void LogError(char *rbuff, Handle elog)
  261. {
  262.     LongInt    len = GetHandleSize(elog);
  263.     LongInt    slen = strlen(rbuff);
  264.     SetHandleSize(elog, len+slen);
  265.     HLock(elog);
  266.     BlockMove(rbuff, &(*elog)[len], slen);
  267.     HUnlock(elog); 
  268. }
  269.  
  270.  
  271. /************************************************************************
  272.  ************************************************************************/
  273. void SetUpSpoolDir()
  274. {
  275.     integer wdRef;
  276.     LongInt wdID;
  277.     integer vol;
  278.  
  279.     GetWDir(&wdRef, &wdID, &vol);
  280.  
  281.     SetToBlessedFolder(SpoolFolder);
  282.  
  283.     GetVol(0L, &spool_dir);
  284.  
  285.     SetWDir(wdRef, wdID, vol);
  286. }
  287.  
  288.  
  289. /************************************************************************
  290.  ************************************************************************/
  291. integer GetLogDir()
  292. {
  293.     integer wdRef, log_dir;
  294.     LongInt wdID;
  295.     integer vol;
  296.  
  297.     GetWDir(&wdRef, &wdID, &vol);
  298.  
  299.     SetToBlessedFolder(SpoolFolder);
  300.  
  301.     GetVol(0L, &log_dir);
  302.  
  303.     SetWDir(wdRef, wdID, vol);
  304.     return log_dir;
  305. }
  306.  
  307.  
  308. /************************************************************************
  309.  ************************************************************************/
  310. Boolean cfA_file(StringPtr nm);
  311. Boolean cfA_file(StringPtr nm)
  312. {
  313.     integer    l = strlen(cfA);
  314.     if (nm[0] < l) return FALSE;
  315.     do    {
  316.         if (nm[l] != cfA[l-1]) return FALSE;
  317.         }
  318.     while (--l);
  319.     return TRUE;
  320. }
  321.  
  322.  
  323. /************************************************************************
  324.  ************************************************************************/
  325. integer EnumerateFiles(integer wdRef, integer *anIndex,
  326.                                 StringPtr name_buf, ctl_def *ctl)
  327. {
  328.     WDPBRec            myWDPB;
  329.     CInfoPBRec        myCIPB;
  330.     integer            retVal = FALSE, osVal, fRef,
  331.                     index = 1;
  332.     Byte            *nm;
  333.  
  334.     if (anIndex) index = *anIndex;
  335.  
  336.     myCIPB.dirInfo.ioVRefNum = wdRef;
  337.     myCIPB.dirInfo.ioNamePtr = name_buf;
  338.     myCIPB.dirInfo.ioFDirIndex = index++;
  339.     myCIPB.dirInfo.ioDrDirID = 0;
  340.     name_buf[0]=0;
  341.  
  342.                     /* get info about object with this name */
  343.     while ( ! PBGetCatInfo(&myCIPB, FALSE) )
  344.         {
  345.         if ( !(myCIPB.dirInfo.ioFlAttrib & 0x10) )
  346.             {                                /* it's not a directory    */
  347.             nm = myCIPB.dirInfo.ioNamePtr;
  348.             if ( cfA_file(nm) )
  349.                 {
  350.                 /* first check that there is a control file for it */
  351.                 if ( ReadCtlFile(nm, ctl) )
  352.                     {
  353.                     /* there aint no ctl file */
  354.                     log_printf("Found a file to print, but can't open it\n");
  355.                     }
  356.                 else
  357.                     {
  358.                     if (anIndex) *anIndex = index;
  359.                     return -1;
  360.                     }
  361.                 }
  362.             }
  363.  
  364.         myCIPB.dirInfo.ioFDirIndex = index++;
  365.         myCIPB.dirInfo.ioDrDirID = 0;
  366.         name_buf[0] = 0;
  367.         }
  368.  
  369.     return 0;
  370. }
  371.  
  372.  
  373. /************************************************************************
  374.  ************************************************************************/
  375.  
  376. #define SendData(s)        PutData(crefnum, (Ptr)&s[1], s[0])
  377. #define SendCData(s,c)    PutData(crefnum, (Ptr)s, c)
  378.  
  379. void PutData(integer crefnum, Ptr data, Word length);
  380. void PutData(integer crefnum, Ptr data, Word length)
  381. {
  382.     integer    state;
  383.  
  384.     TCPSWrite(crefnum, data, length, &state);
  385.  
  386.     WaitForState(&state);
  387. }
  388.  
  389.  
  390. /************************************************************************
  391.  ************************************************************************/
  392. void SendJobs(integer crefnum)
  393. {
  394.     integer        index = 1, count = 0;
  395.     char        lf = 0x0A;
  396.     StringPtr    stat;
  397.     StringPtr    prName;
  398.     Str255        name_buf;
  399.     ctl_def        ctl;
  400.  
  401.     while ( EnumerateFiles(spool_dir, &index, name_buf, &ctl) )
  402.         {                /* files found */
  403.         if (!count++)
  404.             {
  405.             if (printing)
  406.                 {
  407.                 SendData("\pLaserWriter <");
  408.                 if (prName=GetPRName())
  409.                     SendData(prName);
  410.                 SendData("\p>\012");
  411.                 if ((stat = PrinterStatus(prName)) && stat[0])
  412.                     SendData(stat);
  413.                 else if (!stat)
  414.                     SendData("\pnot available");
  415.                 else
  416.                     SendData("\pis printing");
  417.                 SendCData(&lf, 1);
  418.                 }
  419.             SendData("\pOwner       Job    File\012");
  420.             }
  421.         SendCData(ctl.owner, strlen(ctl.owner));
  422.         SendCData("            ", 12-strlen(ctl.owner));
  423.         SendCData((char*)&name_buf[4], 3);
  424.         SendCData("    ", 4);
  425.         SendCData(ctl.src_name, strlen(ctl.src_name));
  426.         SendCData(&lf, 1);
  427.         }
  428.     if (!count)
  429.         SendData("\pno entries\012");
  430. }
  431.